package yang.yu.sunny.application.impl;

import org.dayatang.domain.EntityRepository;
import org.dayatang.utils.BeanUtils;
import yang.yu.sunny.application.OrderDto;
import yang.yu.sunny.application.OrderItemDto;
import yang.yu.sunny.application.SunnyReports;
import yang.yu.sunny.datamodel.OrderData;
import yang.yu.sunny.datamodel.OrderItemData;
import yang.yu.sunny.domain.*;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created by yyang on 16/3/23.
 */
public class SunnyReportsImpl implements SunnyReports {

    private EntityRepository repository;

    private Customers customers;

    private ProductCategories categories;

    private Products products;

    public SunnyReportsImpl(EntityRepository repository) {
        this.repository = repository;
        customers = new Customers(repository);
        categories = new ProductCategories(repository);
        products = new Products(repository);
    }

    @Override
    public OrderDto getOrder(Long orderId) {
        OrderData order = OrderData.get(orderId);
        OrderDto result = new OrderDto();
        new BeanUtils(result).copyPropertiesFrom(order);
        result.setCustomerName(customers.getName(order.getCustomerId()).orElse(""));
        result.setItems(toDto(order.getItems()));
        return result;
    }

    private List<OrderItemDto> toDto(List<OrderItemData> items) {
        Set<Long> productIds = items.stream()
                .map(OrderItemData::getProductId)
                .collect(Collectors.toSet());
        Map<Long, Product> productMap = products.of(productIds);
        Set<Long> categoryIds = productMap.values().stream()
                .map(product -> product.getCategory().getId())
                .collect(Collectors.toSet());
        Map<Long, ProductCategory> categoryMap = categories.of(categoryIds);
        OrderConverter converter = new OrderConverter(productMap, categoryMap);
        return items.stream()
                .map(converter::toDto)
                .collect(Collectors.toList());
    }
}
